package com.ruoyi.framework.config;

import cn.dev33.satoken.interceptor.SaInterceptor;
import cn.dev33.satoken.jwt.StpLogicJwtForSimple;
import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.stp.StpInterface;
import cn.dev33.satoken.stp.StpLogic;
import cn.dev33.satoken.stp.StpUtil;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.service.ISysMenuService;
import com.ruoyi.system.service.ISysUserService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.CollectionUtils;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * SA-Token 配置类
 *
 * @author ruoyi
 */
@Configuration
@RequiredArgsConstructor
public class SaTokenConfig implements WebMvcConfigurer {

    private final ISysUserService userService;
    private final ISysMenuService menuService;

    /**
     * 注册SA-Token拦截器，打开注解式鉴权功能
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 注册Sa-Token拦截器，校验规则为StpUtil.checkLogin()
        registry.addInterceptor(new SaInterceptor(handle -> {
            SaRouter
                    // 拦截所有路由
                    .match("/**")
                    // 排除登录相关接口
                    .notMatch("/login", "/logout", "/register", "/captchaImage")
                    // 排除静态资源
                    .notMatch("/", "/*.html", "/**.html", "/**.css", "/**.js", "/profile/**")
                    // 排除Swagger相关接口
                    .notMatch("/swagger-ui.html", "/v3/api-docs/**", "/swagger-ui/**", "/druid/**")
                    // 排除错误页面
                    .notMatch("/error")
                    // 进行登录校验
                    .check(r -> StpUtil.checkLogin());
        })).addPathPatterns("/**");
    }

    /**
     * 自定义权限验证接口实现
     */
    @Bean
    public StpInterface stpInterface() {
        return new StpInterface() {
            /**
             * 返回当前用户的角色集合
             */
            @Override
            public List<String> getRoleList(Object loginId, String loginType) {
                List<String> roleList = new ArrayList<>();
                try {
                    long userId = Long.parseLong(loginId.toString());
                    // 管理员拥有所有角色
                    if (userId == 1L) {
                        roleList.add(Constants.SUPER_ADMIN);
                    } else {
                        // 根据用户ID查询角色
                        SysUser user = userService.selectUserById(userId);
                        if (user != null && !CollectionUtils.isEmpty(user.getRoles())) {
                            for (SysRole role : user.getRoles()) {
                                if (StringUtils.isNotEmpty(role.getRoleKey())) {
                                    roleList.add(role.getRoleKey());
                                }
                            }
                        }
                    }
                } catch (Exception e) {
                    // 异常情况返回空列表
                }
                return roleList;
            }

            /**
             * 返回当前用户的权限集合
             */
            @Override
            public List<String> getPermissionList(Object loginId, String loginType) {
                List<String> permissionList = new ArrayList<>();
                try {
                    long userId = Long.parseLong(loginId.toString());
                    // 管理员拥有所有权限
                    if (userId == 1L) {
                        permissionList.add(Constants.ALL_PERMISSION);
                    } else {
                        // 根据用户ID查询权限
                        SysUser user = userService.selectUserById(userId);
                        if (user != null) {
                            Set<String> perms = menuService.selectMenuPermsByUserId(userId);
                            if (!CollectionUtils.isEmpty(perms)) {
                                permissionList.addAll(perms);
                            }
                        }
                    }
                } catch (Exception e) {
                    // 异常情况返回空列表
                }
                return permissionList;
            }
        };
    }

    /**
     * SA-Token 整合 jwt (Simple 简单模式)
     */
    @Bean
    public StpLogic getStpLogicJwt() {
        return new StpLogicJwtForSimple();
    }
}